iT邦幫忙

DAY 16
0

科學運算和資料處理的潛力新秀--Julia語言系列 第 16

julia (16) -- 有關效能最佳化的一些小事

  • 分享至 

  • xImage
  •  

今天的主題是如何提高julia程式碼的效能。

在前面的文章裡面一再提到,julia之所以可以非常快,是因為它在語法上讓使用者可以把它寫得很像C語言,讓編譯器容易產生高效的底層實作。

這篇文章會介紹幾個官方文件裡頭提到的Tips來提高程式碼的效能。

第一個重要的技巧是儘可能的宣告變數的type,像是這樣:

function f(a)
    x=a[2]::Int32
    return x+1
end

假設你已經確定知道a[2]會是一個Int32的整數,把x寫成a[2]::Int32不但可以告訴編譯器這份資訊,讓它容易把程式碼最佳化,同時也有assert的功能。一旦a[2]的值不屬於Int32,就會出現執行錯誤。我們還可以更進一步把function argument也加上型別標識:

function f(a::Array{Int32,1})
    x=a[2]::Int32
    return x+1
end

事實上,假如你把julia當做是C語言在使用的話,這麼做其實是一個很自然的選擇。在C裡面這個函數就會長得類似這樣:

int f(int* a)
{
    int x=a[2];
    return x+1;
}

另一個會影響效能的動作是在程式執行期間更改變數的型別,像這樣

x=2
x=2/3

這麼一來x的型別就從整數轉為浮點數。這是julia允許的,因為它還是有高階語言的特性,但是這會降低程式的效率。這也是可以預期的,因為在寫C的時候,變數的type也是一旦決定,就不能更改的。

第二個是要注意多維矩陣的元素取用順序。Julia是沿是矩陣的「行」來二維陣列的,亦即,下面這個二維矩陣:

[1 2;
 3 4;]

在記憶體的存放順序是[1, 3 ,2 4],這個Fortran是一樣的,但是在C語言底下,記憶體存放順序就是[1,2,3,4]。所以要寫迴圈的時候,把column index當外圈會得到比較好的效能,也就是說

for colIndex=1:n
    for rowIndex=1:n
        A[rowIndex][colIndex]=0
end

會比

for rowIndex=1:n
    for colIndex=1:n
        A[rowIndex][colIndex]=0
end

快很多。

第三個就是儘量避免建立新的向量或是矩陣,例如: 可以用 x+y+z的話就不要用 sum([x,y,z])。因為除了建立矩陣這件事之外,另外還有垃圾回收(garbage collection)機制所帶來的時間成本。

要再度提醒大家的是,julia是一個動態性的腳本語言,不需要為了追求效率的極致把自己弄得綁手綁腳。開發初期當然還是寫得順最要緊,然後再從一些效率的瓶頸部份慢慢最佳化。如果每個地方都講求高效,那就去寫C/C++還比較直接。


上一篇
julia (15) -- 2048的AI實作之一
下一篇
julia (17) -- 用julia玩Kaggle(1)
系列文
科學運算和資料處理的潛力新秀--Julia語言30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言